// File: jmcomic-core/src/main/java/dev/jukomu/jmcomic/util/JmPageUtils.java
package dev.jukomu.jmcomic.util;

import dev.jukomu.common.util.json.AdvancedMap;
import dev.jukomu.jmcomic.entity.JmFavoritePage;
import dev.jukomu.jmcomic.entity.JmPageContent.ContentItem;
import dev.jukomu.jmcomic.entity.JmSearchPage;
import dev.jukomu.jmcomic.exception.JmcomicException;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * 对应Python的JmPageTool，提供禁漫分页内容的解析工具。
 */
public class JmPageUtils {

    // 用来缩减HTML的长度
    public static final Pattern PATTERN_HTML_SEARCH_SHORTEN_FOR = Pattern.compile("<div class=\"well well-sm\">([\\s\\S]*)<div class=\"row\">");

    // 用来提取搜索页面的album的信息
    public static final Pattern PATTERN_HTML_SEARCH_ALBUM_INFO_LIST = Pattern.compile(
            "<a href=\"/album/(\\d+)/[\\s\\S]*?title=\"(.*?)\"([\\s\\S]*?)<div class=\"title-truncate tags .*>([\\s\\S]*?)</div>"
    );

    // 用来提取分类页面的album的信息
    public static final Pattern PATTERN_HTML_CATEGORY_ALBUM_INFO_LIST = Pattern.compile(
            "<a href=\"/album/(\\d+)/[^>]*>[^>]*?" +
                    "title=\"(.*?)\"[^>]*>[ \\n]*</a>[ \\n]*" +
                    "<div class=\"label-loveicon\">([\\s\\S]*?)" +
                    "<div class=\"clearfix\">"
    );

    // 用来查找tag列表
    public static final Pattern PATTERN_HTML_SEARCH_TAGS = Pattern.compile("<a[^>]*?>(.*?)</a>");

    // 查找错误，例如 [错误，關鍵字過短，請至少輸入兩個字以上。]
    public static final Pattern PATTERN_HTML_SEARCH_ERROR = Pattern.compile("<fieldset>\\n<legend>(.*?)</legend>\\n<div class=.*?>\\n(.*?)\\n</div>\\n</fieldset>");

    // 搜索结果总数
    public static final Map.Entry<Pattern, Integer> PATTERN_HTML_SEARCH_TOTAL = new AbstractMap.SimpleEntry<>(Pattern.compile("class=\"text-white\">(\\d+)</span> A漫."), 0);

    // 收藏页面的本子结果
    public static final Pattern PATTERN_HTML_FAVORITE_CONTENT = Pattern.compile(
            "<div id=\"favorites_album_[^>]*?>[\\s\\S]*?" +
                    "<a href=\"/album/(\\d+)/[^\\\"]*\">[\\s\\S]*?" +
                    "<div class=\"video-title title-truncate\">([^<]*?)" +
                    "</div>"
    );

    // 收藏夹的收藏总数
    public static final Pattern PATTERN_HTML_FAVORITE_TOTAL = Pattern.compile(" : (\\d+)[^/]*/\\D*(\\d+)");

    // 所有的收藏夹
    public static final List<Pattern> PATTERN_HTML_FAVORITE_FOLDER_LIST = Collections.unmodifiableList(Arrays.asList(
            Pattern.compile("<select class=\"user-select\" name=\"movefolder-fid\">([\\s\\S]*)</select>"),
            Pattern.compile("<option value=\"(\\d+)\">([^<]*?)</option>")
    ));

    /**
     * 从HTML解析搜索页面。
     *
     * @param html HTML内容。
     * @return JmSearchPage实例。
     * @throws JmcomicException 如果解析失败。
     */
    public static JmSearchPage parseHtmlToSearchPage(String html) {
        // 1. 检查是否失败
        PatternUtils.requireNotMatch(
                html,
                PATTERN_HTML_SEARCH_ERROR,
                match -> String.format("%s: %s", match.group(1), match.group(2))
        );

        // 2. 缩小文本范围
        String shortenedHtml = PatternUtils.requireMatch(
                html,
                PATTERN_HTML_SEARCH_SHORTEN_FOR,
                "未匹配到搜索结果",
                1 // group(1) for the content
        );

        // 3. 提取结果
        List<ContentItem> content = new ArrayList<>();
        int total = Integer.parseInt(PatternUtils.matchOrDefault(shortenedHtml, PATTERN_HTML_SEARCH_TOTAL.getKey(), "0"));

        Matcher albumInfoMatcher = PATTERN_HTML_SEARCH_ALBUM_INFO_LIST.matcher(shortenedHtml);
        while (albumInfoMatcher.find()) {
            String albumId = albumInfoMatcher.group(1);
            String title = albumInfoMatcher.group(2);
            // String labelCategoryText = albumInfoMatcher.group(3); // Not used
            String tagText = albumInfoMatcher.group(4);

            List<String> tags = new ArrayList<>();
            Matcher tagsMatcher = PATTERN_HTML_SEARCH_TAGS.matcher(tagText);
            while (tagsMatcher.find()) {
                tags.add(tagsMatcher.group(1));
            }

            Map<String, Object> info = new HashMap<>();
            info.put("name", title);
            info.put("tags", tags);
            content.add(new ContentItem(albumId, info));
        }

        return new JmSearchPage(content, total);
    }

    /**
     * 从HTML解析分类页面。
     *
     * @param html HTML内容。
     * @return JmSearchPage实例（JmCategoryPage的别名）。
     * @throws JmcomicException 如果解析失败。
     */
    public static JmSearchPage parseHtmlToCategoryPage(String html) {
        List<ContentItem> content = new ArrayList<>();
        int total = Integer.parseInt(PatternUtils.matchOrDefault(html, PATTERN_HTML_SEARCH_TOTAL.getKey(), "0"));

        Matcher albumInfoMatcher = PATTERN_HTML_CATEGORY_ALBUM_INFO_LIST.matcher(html);
        while (albumInfoMatcher.find()) {
            String albumId = albumInfoMatcher.group(1);
            String title = albumInfoMatcher.group(2);
            String tagText = albumInfoMatcher.group(3);

            List<String> tags = new ArrayList<>();
            Matcher tagsMatcher = PATTERN_HTML_SEARCH_TAGS.matcher(tagText);
            while (tagsMatcher.find()) {
                tags.add(tagsMatcher.group(1));
            }

            Map<String, Object> info = new HashMap<>();
            info.put("name", title);
            info.put("tags", tags);
            content.add(new ContentItem(albumId, info));
        }
        return new JmSearchPage(content, total);
    }

    /**
     * 从HTML解析收藏页面。
     *
     * @param html HTML内容。
     * @return JmFavoritePage实例。
     * @throws JmcomicException 如果解析失败。
     */
    public static JmFavoritePage parseHtmlToFavoritePage(String html) {
        int total = Integer.parseInt(PatternUtils.requireMatch(
                html,
                PATTERN_HTML_FAVORITE_TOTAL,
                "未匹配到收藏夹的本子总数",
                1 // 获取第一个捕获组，总数
        ));

        // 收藏夹的本子结果
        List<ContentItem> content = new ArrayList<>();
        Matcher contentMatcher = PATTERN_HTML_FAVORITE_CONTENT.matcher(html);
        while (contentMatcher.find()) {
            String albumId = contentMatcher.group(1);
            String albumTitle = contentMatcher.group(2);
            Map<String, Object> info = new HashMap<>();
            info.put("name", albumTitle);
            content.add(new ContentItem(albumId, info));
        }

        // 匹配收藏夹列表
        List<Map<String, String>> folderList = new ArrayList<>();
        Pattern p1 = PATTERN_HTML_FAVORITE_FOLDER_LIST.get(0);
        Pattern p2 = PATTERN_HTML_FAVORITE_FOLDER_LIST.get(1);

        String folderListText = PatternUtils.requireMatch(html, p1, "未匹配到收藏夹列表", 1); // Group 1 contains the content
        Matcher folderListMatcher = p2.matcher(folderListText);
        while (folderListMatcher.find()) {
            String fid = folderListMatcher.group(1);
            String fname = folderListMatcher.group(2);
            Map<String, String> folderInfo = new HashMap<>();
            folderInfo.put("name", fname);
            folderInfo.put("FID", fid);
            folderList.add(folderInfo);
        }

        return new JmFavoritePage(content, folderList, total);
    }

    /**
     * 将API响应数据解析为搜索页面。
     *
     * @param data AdvancedMap形式的API响应数据。
     * @return JmSearchPage实例。
     */
    public static JmSearchPage parseApiToSearchPage(AdvancedMap data) {
        String input = String.valueOf(data.get("total"));
        int total = 0;
        Matcher matcher = Pattern.compile("\\d+").matcher(input);
        try {
            if (matcher.find()) {
                total = Integer.parseInt(matcher.group());
            }
        } catch (NumberFormatException e) {
            throw new RuntimeException(e);
        }
        List<ContentItem> content = adaptContent(data.get("content", Collections.emptyList()));
        return new JmSearchPage(content, total);
    }

    /**
     * 将API响应数据解析为收藏页面。
     *
     * @param data AdvancedMap形式的API响应数据。
     * @return JmFavoritePage实例。
     */
    public static JmFavoritePage parseApiToFavoritePage(AdvancedMap data) {
        int total = data.get("total", 0);
        List<ContentItem> content = adaptContent(data.get("list", Collections.emptyList()));
        List<Map<String, String>> folderList = data.get("folder_list", Collections.emptyList());
        return new JmFavoritePage(content, folderList, total);
    }

    /**
     * 适配API响应中的内容列表。
     *
     * @param apiContentList API返回的原始内容列表。
     * @return 适配后的ContentItem列表。
     */
    private static List<ContentItem> adaptContent(List<Map<String, Object>> apiContentList) {
        return apiContentList.stream()
                .map(itemMap -> {
                    String id = String.valueOf(itemMap.get("id"));
                    // 确保tags字段存在，即使API没有返回
                    itemMap.computeIfAbsent("tags", k -> new ArrayList<>());
                    return new ContentItem(id, new HashMap<>(itemMap)); // Create mutable copy if needed
                })
                .collect(Collectors.toList());
    }

    // 私有构造函数，防止实例化
    private JmPageUtils() {
    }
}